#include <stdio.h>

#include "../src/gtthread.h"

/* Test Case #4
 * 1. main() create thread1()
 * 2. main() join thread1()
 * 3. thread1() create thread2() which yields everytime
 * 4. thread1() call gtthread_self()
 * 5. thread1() call gtthread_exit(&gtthread_self())
 * 6. main() print return value of thread1(), and then exit
 * 
 * Tested functions
 * 1. gtthread_init(1)
 * 2. gtthread_create(3)
 * 3. gtthread_join(2)
 * 4. gtthread_exit(1)
 * 5. gtthread_yield(0)
 * 6. gtthread_self(0)
 */


const int num_threads = 1;
const int period = 10;
void *thread2(void *a);
void *thread1(void* a)
{
    int i = 0;
    int v = *(int*)a;
    int *p = (int*)malloc(sizeof(int));
    printf("[thread %d] started\n", v);
    gtthread_t t2, t, *rt;
    printf("[thread %d] creating thread2\n", v);
    gtthread_create(&t2, thread2, NULL);
    while (i < 10000000) {
        if (i % 1000000 == 0) 
            printf("[thread%d] is still running\n", v);
        ++i;
    }
    t = gtthread_self();
    rt = (gtthread_t*)malloc(sizeof (gtthread_t));
    *rt = t;
    printf("[thread %d] finished, return self() is %d\n", v, (int)(*rt));
    gtthread_exit((void *)rt);
}

void *thread2(void *a)
{
    int i = 0;
    printf("[yieldthread] started\n");
    while (i < 3) {
        printf("[yieldthread] yield\n");
        gtthread_yield();
        ++i;
    }
    printf("[yieldthread] finished\n");
}

int main()
{
    int i, o[num_threads];
    int a;
//    int *rt[num_threads];
    gtthread_t *rt;
    for (i=0; i<num_threads; i++) {
        rt[i] = (int *)malloc(sizeof(int));
        o[i] = i;
    }
    puts("[main] started");
    gtthread_init(period);
    gtthread_t yth, th[num_threads];

    for (i=0; i<num_threads; ++i) {
        gtthread_create(&th[i], thread1, (void*)&o[i]);
    }
//    for (i=0; i<num_threads; ++i) {
        gtthread_join(th[0], (void*)&rt);
//    }
    //for (i=0; i<num_threads; ++i)
        printf("[main] rt thread1 handle: %d\n", *rt);
    puts("[main] finished");
    return 0;
}





